package com.wanli.storemobile.utils;

import android.content.Context;
import android.content.SharedPreferences;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.gson.Gson;
import com.wanli.storemobile.MyApplication;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

/**
 *
 */

public class SPUtils {
    //保存在手机里面的文件名
    public static final String FILE_NAME = "help_cashier";
    public static SharedPreferences sp;


    private static SharedPreferences init() {
        if (sp == null) {
            sp = MyApplication.getContext().getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
        }
        return sp;
    }

    public static <E> void put(@NonNull String key, @NonNull E value) {
        SharedPreferences.Editor editor = init().edit();
        if (value instanceof String || value instanceof Integer//
                || value instanceof Boolean || value instanceof Float//
                || value instanceof Long || value instanceof Double) {
            editor.putString(key, String.valueOf(value));
        } else {
            editor.putString(key, new Gson().toJson(value));
        }
        SPCompat.apply(editor);
    }

    public static <E> void put(@NonNull String key, @NonNull Set<String> defValues) {
        SharedPreferences.Editor editor = init().edit();
        editor.putStringSet(key, defValues);
        SPCompat.apply(editor);
    }


    public static <E> E get(@NonNull String key, @NonNull E defaultValue) {
        String value = init().getString(key, String.valueOf(defaultValue));
        if (defaultValue instanceof String) {
            return (E) value;
        }
        if (defaultValue instanceof Integer) {
            return (E) Integer.valueOf(value);
        }
        if (defaultValue instanceof Boolean) {
            return (E) Boolean.valueOf(value);
        }
        if (defaultValue instanceof Float) {
            return (E) Float.valueOf(value);
        }
        if (defaultValue instanceof Long) {
            return (E) Long.valueOf(value);
        }
        if (defaultValue instanceof Double) {
            return (E) Double.valueOf(value);
        }
        //json为null的时候返回对象为null,gson已处理
        return (E) new Gson().fromJson(value, defaultValue.getClass());
    }

    public static Set<String> get(@NonNull String key, @Nullable Set<String> defValues) {
        return init().getStringSet(key, defValues);
    }


    /**
     * 移除某个key值已经对应的值
     *
     * @param key
     */
    public static void remove(String key) {
        SharedPreferences.Editor editor = init().edit();
        editor.remove(key);
        SPCompat.apply(editor);
    }

    /**
     * 清除所有数据
     */
    public static void clear() {
        SharedPreferences.Editor editor = init().edit();
        editor.clear();
        SPCompat.apply(editor);
    }

    /**
     * 查询某个key是否已经存在
     */
    public static boolean contains(String key) {
        return init().contains(key);
    }

    /**
     * 返回所有的键值对
     */
    public static Map<String, ?> getAll() {
        return init().getAll();
    }

    /**
     * 保存对象到sp文件中 被保存的对象须要实现 Serializable 接口
     */
    public static void saveObject(String key, Object value) {
        put(key, value);
    }

    /**
     * desc:获取保存的Object对象
     */
    public static <T> T readObject(String key, Class<T> clazz) {
        try {
            return (T) get(key, clazz.newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     */
    private static class SPCompat {
        private static final Method S_APPLY_METHOD = findApplyMethod();

        /**
         * 反射查找apply的方法
         */
        @SuppressWarnings({"unchecked", "rawtypes"})
        private static Method findApplyMethod() {
            try {
                Class clz = SharedPreferences.Editor.class;
                return clz.getMethod("apply");
            } catch (NoSuchMethodException e) {
            }
            return null;
        }

        /**
         * 如果找到则使用apply执行，否则使用commit
         */
        public static void apply(SharedPreferences.Editor editor) {
            try {
                if (S_APPLY_METHOD != null) {
                    S_APPLY_METHOD.invoke(editor);
                    return;
                }
            } catch (Exception e) {
            }
            editor.commit();
        }
    }
}